<!--
 * @Author: WangGuojian 1085844536@qq.com
 * @Date: 2023-08-09 18:37:46
 * @LastEditTime: 2023-08-09 18:57:05
 * @LastEditors: WangGuojian 1085844536@qq.com
 * @FilePath: \vue-basic\12-列表渲染\2.key的原理.html
 * @Description:
-->
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>key的原理</title>
        <script type="text/javascript" src="../js/vue.js"></script>
    </head>
    <body>
        <!--
            面试题：react、vue中的key有什么作用？（key的内部原理）

                1.虚拟DOM中key的作用：
                    key是虚拟DOM中对象的标识，当数据发生变化时，Vue会根据新数据生成新的虚拟DOM，
                    随后Vue进行新虚拟DOM与旧虚拟DOM的差异比较 ，比较规则如下

                2.对比规则：
                    a.旧虚拟DOM中找到了与新虚拟DOM相同的key
                        ⅰ. 若虚拟DOM中内容没变, 直接使用之前的真实DOM
                        ⅱ. 若虚拟DOM中内容变了, 则生成新的真实DOM，随后替换掉页面中之前的真实DOM

                    b.旧虚拟DOM中未找到与新虚拟DOM相同的key
                        创建新的真实DOM，随后渲染到到页面

                3. 用index作为key可能会引发的问题
                    a. 若对数据进行逆序添加、逆序删除等破坏顺序操作：
                            会产生没有必要的真实DOM更新 ==> 界面效果没问题，但效率低

                    b. 若结构中还包含输入类的DOM：
                            会产生错误DOM更新 ==> 界面有问题

                4. 开发中如何选择key？
                    a. 最好使用每条数据的唯一标识作为key，比如 id、手机号、身份证号、学号等唯一值
                    b. 如果不存在对数据的逆序添加、逆序删除等破坏顺序的操作，
                        仅用于渲染列表，使用index作为key是没有问题的
         -->
        <div id="root">
            <!-- 遍历数组 -->
            <h2>人员列表（遍历数组）</h2>
            <button @click.once="add">添加一个老刘</button>
            <ul>
                <li v-for="(p,index) of persons" :key="p.id">
                    {{ p.name }}-{{ p.age }}
                    <input type="text" />
                </li>
            </ul>
        </div>
    </body>

    <script type="text/javascript">
        Vue.config.productionTip = false;
        new Vue({
            el: '#root',
            data: {
                persons: [
                    { id: '001', name: '张三', age: 18 },
                    { id: '002', name: '李四', age: 19 },
                    { id: '003', name: '王五', age: 20 },
                ],
            },
            methods: {
                add() {
                    const p = { id: '004', name: '老刘', age: 40 };
                    this.persons.unshift(p);
                },
            },
        });
    </script>
</html>
